<?php
namespace api\user\controller;

use api\user\model\UserMinerModel;
use api\user\model\MinerModel;
use api\user\model\UserModel;
use api\common\controller\RestUserBaseController;
use think\Db;
use api\user\model\ConfigModel;

class MinerController extends RestUserBaseController
{
    protected $UserMinerModel;

    public function __construct()
    {
        parent::__construct();
        $this->UserMinerModel = new UserMinerModel();
        $this->UserModel = new UserModel();
    }

    /**
     * 我的矿机
     * @author M
     * @data             2020-02-08
     * @return [type] [description]
     */
    public function index()
    {
        $param          = $this->request->param();
        $now = strtotime(date('Y-m-d'));
        $param['where'] = [
            'user_id' => $this->userId,
            'status'  => 1,
        ];
//        $param['relation'] = 'miner';
//        $param['order'] = '-createtime';
        $total_arithmetic_value = $this->UserMinerModel
        ->where($param['where'])
        ->sum('arithmetic_value');
        
//        $data = $this->UserMinerModel->getDatas($param);
        $data = $this->UserMinerModel
        ->where(['user_id' => $this->userId])
        ->order('createtime desc')->select();

        $output_value    = ConfigModel::getConfig('miner','output_value');
        $arithmetic_value    = ConfigModel::getConfig('miner','arithmetic_value');
        if($output_value['value']>0){
            $miner['user_id'] = $this->userId;
            $miner['miner_id'] = 0;
            $miner['status'] = 1;
            $miner['miner_name'] ='体验矿机';
            $miner['output_value'] = $output_value['value'];
            $miner['arithmetic_value'] = $arithmetic_value['value'];
            $total_arithmetic_value = $total_arithmetic_value+$arithmetic_value['value'];
            $data[] = $miner;
        }
        
        // foreach($data as &$v){
        //     if(!empty($v['from_id'])){
        //         $v['from_phone'] = Db::name('user')->where('id',$v['from_id'])->value('mobile');
        //     }
        //     $v['sum'] = Db::name('user_output_log')->where(['user_id'=>$v['user_id'],'miner_id'=>$v['miner_id'],'status'=>1])->sum('output');
        //     $v['limit'] = Db::name('miner')->where('id',$v['miner_id'])->value('output_limit');
        //     $v['today'] = Db::name('user_miner')->where(['user_id'=>$v['user_id'],'miner_id'=>$v['miner_id']])->whereTime('createtime', 'd')->count();
        //     $v['today_limit'] = $v['limit'] - $v['today'];
        //     $v['miner']  = Db::name('miner')->where('id',$v['miner_id'])->find();
        // }
        $this->success('请求成功', [
            'total_mu_achievement'=>$this->user['total_mu_achievement'], 
            'total_mq_achievement'=>$this->user['total_mq_achievement'], 
            'total_arithmetic_value'=>$total_arithmetic_value,
            'list' => $data
        ]);
    }

    /**
     * 矿机激活
     * @author M
     * @data             2020-02-09
     * @return [type] [description]
     */
    public function active()
    {
        $param = $this->request->param();
        if(empty($param['miner_id'])){
            $this->error("参数错误");
        }
        $verify_switch = getconfig('verify_switch');
        if($verify_switch>0){
          if(empty($this->user['verify_status'])){
            $this->error(['code' => 10052, 'msg' => '请先完成实名认证']);
            }  
        }
        
        if (empty($this->user['pay_password'])) {
            $this->error(['code' => 10051, 'msg' => '请先设置支付密码']);
        }
        if ($this->user['pay_password'] != getEncryptPassword($param['pay_password'], $this->user['pay_salt'])) {
            $this->error('支付密码错误');
        }
        $user_info = Db::name('user')->where('id',$this->userId)->lock(true)->find();
        $minerData = $this->UserMinerModel
        ->where(['id'=>$param['miner_id'],'user_id' => $this->userId,'status'=>2])
        ->find();
        $active_price = Db::name('miner')->where(['id'=>$minerData['miner_id']])->value('active_price');
        if($minerData){
            if($active_price){
                if($active_price>$user_info['mq']){
                    $this->error('你的MQ资产不足');
                }
            }
            // 启动事务
            Db::startTrans();
            try {
                $needmq    = $active_price;
                Db::name('user_miner')
                ->where(['id'=>$param['miner_id']])
                ->update(['status'=>1,'active_time' => time()]);
                //扣除激活消耗的MQ
                Db::name('user')
                ->where('id', $this->userId)
                ->setDec('mq', $needmq);
                //来源:1=币币交易买入,2=币币交易卖出,3=OTC通道买入,4=OTC通道卖出,5=矿机收益,6=动态奖励,7=购买矿机,8=激活矿机,9=撤销订单,10=空投
                $user_balance_log['user_id']    = $this->userId;
                $user_balance_log['amount']     = $needmq;
                $user_balance_log['before']     = $user_info['mq'];
                $user_balance_log['after']      = $user_info['mq'] - $needmq;
                $user_balance_log['remark']     = '激活矿机';
                $user_balance_log['type']       = 0;
                $user_balance_log['log_type']   = 3;
                $user_balance_log['source']     = 8;
                $user_balance_log['createtime'] = time();
                Db::name('user_balance_log')->insert($user_balance_log);
                // 提交事务
                Db::commit();
                $this->success('激活成功');
            } catch (\think\Exception\DbException $exception) {
                // 回滚事务
                Db::rollback();
                //$this->error($exception->getMessage());
                $this->error('激活失败');
            }
        }else{
            $this->error('激活失败');
        }
    }
    /**
     * 矿机收益
     * @author M
     * @data             2020-02-09
     * @return [type] [description]
     */
    public function profit(){
        $map['status'] = 0;
        $map['user_id'] = $this->userId;
        $data = Db::name('user_output_log')
        ->where($map)
        ->select();
        $runing_count = Db::name('user_miner')
        ->where(['user_id'=>$this->userId,'status'=>1])
        ->count();
        $wait_count = Db::name('user_miner')
        ->where(['user_id'=>$this->userId,'status'=>2])
        ->count();
        $active_sum = Db::name('user_miner')
        ->where(['user_id'=>$this->userId])
        ->where('status','neq',0)
        ->sum('active_price');
        $this->success('请求成功', ['list' => $data,'runing_count'=>$runing_count,'wait_count'=>$wait_count,'active_sum'=>$active_sum]);
    }

    /**
     * 矿机收益领取
     * @author M
     * @data             2020-02-09
     * @return [type] [description]
     */
    public function draw()
    {
        $param = $this->request->param();
        $type = isset($param['type'])?$param['type']:0;
        //一键领取
        if($type ==1){
            $map['status'] = 0;
            $map['user_id'] = $this->userId;
            // 启动事务
            Db::startTrans();
            $userinfo = Db::name('user') ->where('id',$this->userId)->lock(true)->find();
            $user_output_sum = Db::name('user_output_log')
            ->where($map)
            ->lock(true)
            ->sum('output'); 
            if($user_output_sum){
                try{
                   $res =  Db::name('user')
                    ->where('id',$this->userId)
                    ->update([
                        'mq'=> Db::raw('mq+'.$user_output_sum),
                        'total_miner_achievement' => Db::raw('total_miner_achievement+'.$user_output_sum),
                    ]);
                    if($res){
                        //来源:1=币币交易买入,2=币币交易卖出,3=OTC通道买入,4=OTC通道卖出,5=矿机收益,6=动态奖励,7=购买矿机,8=激活矿机,9=撤销订单,10=空投
                        $user_balance_log['user_id']      = $this->userId;
                        $user_balance_log['amount']       = $user_output_sum;
                        $user_balance_log['before']       = $userinfo['mq'];
                        $user_balance_log['after']        = $userinfo['mq']+$user_output_sum;
                        $user_balance_log['remark']       = '矿机收益';
                        $user_balance_log['type']         = 1;
                        $user_balance_log['log_type']     = 3;
                        $user_balance_log['source']       = 5;
                        $user_balance_log['createtime']   = time();
                        Db::name('user_balance_log')->insert($user_balance_log);
                    } 
                    Db::name('user_output_log')->where('user_id',$this->userId)->delete();
                    // 提交事务
                    Db::commit();
                    $this->success("领取成功",['output_sum'=>$user_output_sum]);
                } catch (\think\Exception\DbException $exception){
                    Db::rollback();
                    //$this->error($exception->getMessage());
                    $this->error("领取失败");
                }
                
            }else{
                $this->error("无任何收益");
            }

        }else{
            if(empty($param['id'])){
                $this->error("参数错误");
            }
            $map['id']      = $param['id'];
            $map['status'] = 0;
            $map['user_id'] = $this->userId;
            // 启动事务
            Db::startTrans();
            $userinfo = Db::name('user') ->where('id',$this->userId)->lock(true)->find();
            $user_output_log = Db::name('user_output_log')
            ->where($map)
            ->find();
            if($user_output_log){
                try{
                    $res =  Db::name('user')
                    ->where('id',$this->userId)
                    ->update([
                        'mq'=> Db::raw('mq+'.$user_output_log['output']),
                        'total_miner_achievement' => Db::raw('total_miner_achievement+'.$user_output_log['output']),
                    ]);
                    if($res){
                        //来源:1=币币交易买入,2=币币交易卖出,3=OTC通道买入,4=OTC通道卖出,5=矿机收益,6=动态奖励,7=购买矿机,8=激活矿机,9=撤销订单,10=空投
                        $user_balance_log['user_id']    = $this->userId;
                        $user_balance_log['amount']     = $user_output_log['output'];
                        $user_balance_log['before']     = $userinfo['mq'];
                        $user_balance_log['after']      = $userinfo['mq']+$user_output_log['output'];
                        $user_balance_log['remark']     = '矿机收益';
                        $user_balance_log['type']       = 1;
                        $user_balance_log['log_type']   = 3;
                        $user_balance_log['source']     = 5;
                        $user_balance_log['createtime'] = time();
                        Db::name('user_balance_log')->insert($user_balance_log);
                    }
                    Db::name('user_output_log')->where('id',$param['id'])->delete();
                    // 提交事务
                    Db::commit();
                   $this->success("领取成功");
                } catch (\think\Exception\DbException $exception){
                    Db::rollback();
                    $this->error("领取失败");
                }
            }else{
                $this->error("领取失败");
            }
        }
    }
    /**
     * 矿机购买
     * @author M
     * @data             2020-02-08
     * @return [type] [description]
     */
    public function save()
    {
        $param         = $this->request->param();
        $verify_switch = getconfig('verify_switch');
        if($verify_switch>0){
          if(empty($this->user['verify_status'])){
            $this->error(['code' => 10052, 'msg' => '请先完成实名认证']);
            }  
        }
        
        $result = $this->validate($param, 'Miner');
        if ($result !== true) {
            $this->error($result);
        }
        if (empty($this->user['pay_password'])) {
            $this->error(['code' => 10051, 'msg' => '请先设置支付密码']);
        }
        if ($this->user['pay_password'] != getEncryptPassword($param['pay_password'], $this->user['pay_salt'])) {
            $this->error('支付密码错误');
        }

        $number = isset($param['number']) ? intval($param['number']) : 1;
        if ($number > 3 || $number < 1) {
            $this->error('购买数量不合法');
        }
        //加锁
        $file = fopen("../lock/buyminerlock.txt", "r");
        //进行排它型锁定,阻塞:后面的进程会一直等待前面的进程执行完毕
        if (flock($file, LOCK_EX)) {//加锁
            
            $user_miner_count = Db::name('user_miner')
            ->where('user_id', $this->userId)
            ->where('miner_id','>',0)
            ->whereTime('createtime', 'd')
            ->lock(true)
            ->count();
            //每日购买上限
            $buy_miner_today_max = getconfig('buy_miner_today_max');
            if (!empty($buy_miner_today_max)) {
                if ($user_miner_count + $number > $buy_miner_today_max) {
                    $this->error('今日购买矿机已达上限');
                }
            }
            $minerData = Db::name('miner')->where('id', $param['id'])->find();
            //矿机的库存检测
            $total_buy = Db::name('user_miner')
            ->where(['miner_id'=>$minerData['id']])
            ->lock(true)
            ->count();
            
            if ($total_buy + $number > $minerData['surplus']) {
                $this->error('当前矿机已售罄，团队正在备货');
            }

            //每日矿机的购买上限 
            $today_count = Db::name('user_miner')
            ->where('miner_id', $minerData['id'])
            ->whereTime('createtime', 'd')
            ->count();
            if ($today_count + $number > $minerData['day_limit']) {
                $this->error('今日矿机已售罄');
            }

            //用户该矿机持有上限
            $miner_count = Db::name('user_miner')
            ->where('user_id', $this->userId)
            ->where('miner_id', $minerData['id'])
            ->where('status', 1)
            ->count();

            if ($miner_count + $number > $minerData['miner_limit']) {
                $this->error('您累计购买的该矿机已达到上限');
            }

            $total_price = $number * $minerData['price'];
            $total_output_value = $minerData['arithmetic_value'] * $number * 24;
            $user_info = Db::name('user')->where('id',$this->userId)->lock(true)->find();
            if ($minerData) {
                //购买类型:1=MU,2=MQ
                if ($minerData['miner_cat'] == 1) {
                    if ($param['type'] == 1) {
                        if($total_price>$user_info['pay_mu']){
                            $this->error('你的充值MU资产不足');
                        }else{
                            $wallet_type = 'pay_mu';
                            $buy_type    = 1;
                        }
                    }elseif($param['type'] == 2){
                        if($total_price>$user_info['active_mu']){
                            $this->error('你的活动MU资产不足');
                        }else{
                            $wallet_type = 'active_mu';
                            $buy_type    = 2;
                        }
                    }else{
                        $this->error('该矿机只支持MU资产购买');
                    }
                } elseif ($minerData['miner_cat'] == 2) {
                    if ($param['type'] != 3) {
                        $this->error('该矿机只支持MQ资产购买');
                    }

                    if($total_price>$user_info['mq']){
                        $this->error('你的MQ资产不足');
                    }else{
                        $wallet_type = 'mq';
                        $buy_type    = 3;
                    }
                }
            } else {
                $this->error('购买失败');
            }
            //我的矿机
            $now                            = time();
            $createtime                     = strtotime(date("Y-m-d",strtotime("+1 day")));//取当前时间整点+1小时
            $endtime                        = $createtime+$minerData['run_cycle']*3600*24;
            $user_miner['user_id']          = $this->userId;
            $user_miner['miner_id']         = $param['id'];
            $user_miner['miner_name']       = $minerData['miner_name'];
            $user_miner['output_value']     = $minerData['output_value'];
            $user_miner['arithmetic_value'] = $minerData['arithmetic_value'];
            $user_miner['price']            = $minerData['price'];
            $user_miner['active_price']     = $minerData['active_price'];
            $user_miner['buy_type']         = $buy_type;
            $user_miner['status']           = 1;//第一次购买自动激活
            $user_miner['miner_cat']        = $minerData['miner_cat'];
            $user_miner['run_cycle']        = $minerData['run_cycle'];
            $user_miner['createtime']       = $createtime;
            $user_miner['endtime']          = $endtime;
            //来源:1=币币交易买入,2=币币交易卖出,3=OTC通道买入,4=OTC通道卖出,5=矿机收益,6=动态奖励,7=购买矿机,8=激活矿机,9=撤销订单,10=空投
            $user_balance_log['user_id']    = $this->userId;
            $user_balance_log['amount']     = $total_price;
            $user_balance_log['before']     = $user_info[$wallet_type];
            $user_balance_log['after']      = $user_info[$wallet_type] - $total_price;
            $user_balance_log['remark']     = '购买矿机';
            $user_balance_log['type']       = 0;
            $user_balance_log['log_type']   = $buy_type;
            $user_balance_log['source']     = 7;
            $user_balance_log['createtime'] = time();
            
            $invite = Db::name('invite')->where('user_id', $this->userId)->find();
            $all_parentid = explode(',', $invite['path']);
            // 启动事务
            Db::startTrans();
            try {
                Db::name('user_miner')->insert($user_miner);
                Db::name('user_balance_log')->insert($user_balance_log);
                Db::name('user')
                ->where('id', $this->userId)
                ->update([
                    $wallet_type => Db::raw($wallet_type . '-' . $total_price),
                    'total_miner_price' => Db::raw('total_miner_price+' . $total_price),
                ]);
                
                array_pop($all_parentid); //剔除自己
                $achievement_type = $buy_type>2?'total_mq_achievement':'total_mu_achievement';
                $reward_type = $buy_type>2?'total_mq_reward':'total_mu_reward';
                //更新所有团队业绩
                $user = Db::name('user')
                ->where('id', 'in', $all_parentid)
                ->setInc($achievement_type, $total_price);

                //动态奖励
                $all_reward = Db::name('user')
                ->where('id', 'in', $all_parentid)
                ->field('id,pay_mu,active_mu,mq')
                ->order('id desc')
                ->limit(9)
                ->select();
                foreach ($all_reward as $key => $value) {
                    switch ($key) {
                        case 0:
                            $range = 0.05;
                            break;
                        case 1:
                            $range = 0.04;
                            break;
                        case 2:
                            $range = 0.03;
                            break;
                        case 3:
                            $range = 0.02;
                            break;
                        case 4:
                            $range = 0.01;
                            break;
                        case 5:
                            $range = 0.01;
                            break;
                        case 6:
                            $range = 0.01;
                            break;
                        case 7:
                            $range = 0.01;
                            break;
                        case 8:
                            $range = 0.01;
                            break;
                        case 9:
                            $range = 0.01;
                            break;
                        default:
                            # code...
                            break;
                    }
                        $reward = $total_price*$range;
                        $wallet_field = $buy_type<3?'active_mu':'mq';
                        $buy_type_field = $buy_type<3?2:3;
                        //来源:1=币币交易买入,2=币币交易卖出,3=OTC通道买入,4=OTC通道卖出,5=矿机收益,6=动态奖励,7=购买矿机,8=激活矿机,9=撤销订单,10=空投
                        $userreward_balance_log['user_id']    = $value['id'];
                        $userreward_balance_log['amount']     = $reward;
                        $userreward_balance_log['before']     = $value[$wallet_field];
                        $userreward_balance_log['after']      = $value[$wallet_field] + $reward;
                        $userreward_balance_log['remark']     = '动态奖励';
                        $userreward_balance_log['type']       = 1;
                        $userreward_balance_log['log_type']   = $buy_type_field;
                        $userreward_balance_log['source']     = 6;
                        $userreward_balance_log['createtime'] = time();
                        Db::name('user')
                        ->where('id', $value['id'])
                        ->update([
                            $wallet_field => Db::raw($wallet_field . '+' . $reward),
                            $reward_type => Db::raw($reward_type . '+' . $reward)
                        ]);
                        //->setInc($wallet_type, $reward);
                        Db::name('user_balance_log')->insert($userreward_balance_log);
                    }
                //$isPushed = addQueue($new_user_miner_ids, 'reward');//奖励抛入队列执行
                // 提交事务
                Db::commit();
                $this->success('购买成功');
            } catch (\think\Exception\DbException $exception) {
                // 回滚事务
                Db::rollback();
                //$this->error($exception->getMessage());
                $this->error('购买失败');
            }

            //释放锁
            flock($file, LOCK_UN);
        }
        fclose($file);

    }

}
